import { Alike, Expect } from "@type-challenges/utils";
// type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y
//   ? 1
//   : 2
//   ? true
//   : false;

// type Chainable = {
//   option<CH extends { [key: string]: unknown }, K extends string, V>(
//     this: CH,
//     key: K,
//     value: Equal<CH[K], V> extends true ? never : V
//   ): { [P in keyof CH | K]: P extends K ? V : CH[P] };
//   get<CH>(this: CH): Omit<CH, keyof Chainable>;
// };

type Chainable<init = {}> = {
  option<K extends string, V extends any>(
    key: K extends keyof init ? never : K,
    value: V
  ): Chainable<init & Record<K, V>>;
  get(): init;
};

declare const a: Chainable;
const a = {
  option: (k, v) => {
    return a;
  },
};

const result = a
  .option("foo", 123)
  .option("bar", { value: "Hello World" })
  .option("name", "type-challenges")
  .get();

type cases = [Expect<Alike<typeof result, Expected>>];

type Expected = {
  foo: number;
  bar: {
    value: string;
  };
  name: string;
};
